package yf.mall.service.impl.app;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.yf.entity.TokenEntity;
import com.yf.response.RRException;
import com.yf.service.TokenService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;
import yf.mall.utils.StringUtil;
import yf.mall.dao.UserDao;
import yf.mall.entity.UserEntity;
import yf.mall.service.app.AppUserService;
import yf.mall.service.app.LoginService;
import yf.mall.vo.app.*;

import javax.annotation.Resource;
import java.util.Optional;

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    @Resource
    private UserDao userDao;

    @Resource
    private WxMaService wxMaService;

    @Resource
    private AppUserService appUserService;

    @Resource
    private TokenService tokenService;


    @Override
    public PhoneLoginVO phoneLogin(PhoneLoginDTO phoneLoginDTO) {
        if (!StringUtil.isPhone(phoneLoginDTO.getPhone())) {
            throw new RRException("手机号有误");
        }
        if(phoneLoginDTO.getPlatform() == null){
            throw new RRException("登录平台信息必传");
        }
        //TODO 暂不判断验证码 前端简单验证下
        UserEntity user = userDao.findByMobile(phoneLoginDTO.getPhone());
        if (user == null) {
            //是注册
            if (Optional.ofNullable(phoneLoginDTO.getIsRegister()).orElse(false)) {
                //注册
                user = appUserService.phoneRegister(phoneLoginDTO.getTopCode(), phoneLoginDTO.getPhone());
            } else {
                throw new RRException("用户不存在");
            }
        }
        updateWxId(user, phoneLoginDTO.getCode(), phoneLoginDTO.getUnionId(), phoneLoginDTO.getOpenId());
        TokenEntity tokenEntity = tokenService.createToken(user.getId(), phoneLoginDTO.getPlatform());
        return new PhoneLoginVO(tokenEntity);
    }


    @Override
    public CodeLoginVO codeLogin(CodeLoginDTO codeLoginDTO) {
        if (!StringUtil.isPhone(codeLoginDTO.getPhone())) {
            throw new RRException("手机号有误");
        }
        if(codeLoginDTO.getPlatform() == null){
            throw new RRException("登录平台信息必传");
        }
        UserEntity user = userDao.findByMobile(codeLoginDTO.getPhone());
        if (user == null) {
            throw new RRException("用户不存在");
        }
        updateWxId(user, codeLoginDTO.getCode(), codeLoginDTO.getUnionId(), codeLoginDTO.getOpenId());
        TokenEntity tokenEntity = tokenService.createToken(user.getId(), codeLoginDTO.getPlatform());
        return new CodeLoginVO(tokenEntity);
    }

    private void updateWxId(UserEntity user, String code, String unionId, String openId) {
        //openId不存在 code换取
        if (StringUtil.isBlank(openId) && !StringUtil.isBlank(code)) {
            try {
                WxMaJscode2SessionResult result = wxMaService.jsCode2SessionInfo(code);
                unionId = result.getUnionid();
                openId = result.getOpenid();
            } catch (WxErrorException e) {
                log.error("小程序jsCode2Session失败", e);
            }
        }
        if (!StringUtil.isBlank(unionId)) {
            user.setUnionId(unionId);
        }
        if (!StringUtil.isBlank(openId)) {
            user.setMiniOpenId(openId);
        }
        userDao.update(user);
    }

    @Override
    public WxMiniLoginVO wxMiniLogin(WxMiniLoginDTO wxMiniLoginDTO) {
        try {
            WxMaJscode2SessionResult result = wxMaService.jsCode2SessionInfo(wxMiniLoginDTO.getCode());
            String unionId = result.getUnionid();
            String openId = result.getOpenid();
            String wxId = unionId;
            if (StringUtil.isBlank(wxId)) {
                wxId = openId;
            }
            UserEntity user = userDao.findByWxId(wxId);
            WxMiniLoginVO wxMiniLoginVO = new WxMiniLoginVO();
            if (user == null) {
                wxMiniLoginVO.setLoginSuccess(false);
                wxMiniLoginVO.setWxResult(result);
            } else {
                wxMiniLoginVO.setToken(tokenService.createToken(user.getId(), 1));
                wxMiniLoginVO.setLoginSuccess(true);
            }
            return wxMiniLoginVO;
        } catch (WxErrorException e) {
            log.error("小程序jsCode2Session失败", e);
            throw new RRException("登录失败!");
        }
    }

    @Override
    public boolean logout(Long userId) {
        if (userId == null) {
            log.info("登出的用户id为空，不处理");
            return false;
        }
        TokenEntity token = tokenService.findByUserIdAndType(userId, 1);
        if (token == null) {
            log.info("通过userId[{}]查询不到对应的token，暂不出来", userId);
            return false;
        }
        return tokenService.delete(token.getId()) > 0;
    }
}
